<template>
  <div
    ref="systemWindowDom"
    class="system-window"
    :data-task-id="taskId"
    :class="{
      full: isFull,
      max: isMax,
      drag: isDrag || dragStart || dragResizeStart,
      min: isMin,
      tray: isTray,
      'no-drag-bar': !isTopBar,
      ios: systemSettingStore.$state.deskAppRangeType === 'ios'
    }"
    :style="systemWindowStyle"
    @mousedown.stop.prevent="handleSystemMousedown"
  >
    <div v-if="isTopBar" class="inner">
      <div
        v-if="systemSettingStore.$state.deskAppRangeType === 'win'"
        class="system-drag-bar"
        @dblclick.stop="handleMaxMin"
        @mousedown.stop="handleMousedownDrag"
      >
        <div class="system-title pl15">
          <span v-if="title">{{ title }}</span>
        </div>
        <div class="system-button" @mousedown.stop @dblclick.stop>
          <span @click.stop="handleMinimization">
            <i class="iconfont wos-minimization fs10" />
          </span>
          <span @click.stop="handleMaxMin">
            <i v-if="!isMax" class="iconfont wos-maximize fs10" />
            <i v-else class="iconfont wos-recover-window fs10" />
          </span>
          <span @click.stop="handleClose">
            <i class="iconfont wos-close fs10" />
          </span>
        </div>
      </div>
      <div
        v-else-if="systemSettingStore.$state.deskAppRangeType === 'ios'"
        class="system-drag-bar"
        @dblclick.stop="handleMaxMin"
        @mousedown.stop="handleMousedownDrag"
      >
        <div
          class="system-button-ios"
          :class="{ blur: runningTasksStore.$state.currentTaskAppId !== appId }"
          @mousedown.stop
          @dblclick.stop
        >
          <span @click.stop="handleClose">
            <i class="iconfont wos-close fs6" />
          </span>
          <span @click.stop="handleMinimization">
            <i class="iconfont wos-minimization fs6" />
          </span>
          <span @click.stop="handleMaxMin">
            <i v-if="!isMax" class="iconfont wos-maximize fs6" />
            <i v-else class="iconfont wos-recover-window fs6" />
          </span>
        </div>
      </div>

      <div class="sort">
        <slot></slot>
      </div>
    </div>
    <div v-else class="no-top-bar" @dblclick.stop="handleMaxMin" @mousedown.stop="handleMousedownDrag">
      <slot></slot>
    </div>
    <div v-if="isResize" class="change-resize" @mousedown.stop="handleResizeMouseDown">
      <div class="modal" v-if="dragResizeStart"></div>
      <span class="row left" data-resize="left" />
      <span class="row right" data-resize="right" />
      <span class="col top" data-resize="top" />
      <span class="col bottom" data-resize="bottom" />
      <span class="box top-left" data-resize="top-left" />
      <span class="box top-right" data-resize="top-right" />
      <span class="box bottom-right" data-resize="bottom-right" />
      <span class="box bottom-left" data-resize="bottom-left" />
    </div>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, provide } from 'vue'
import { useRunningTasksStore } from '@/stores/taskBar/runningTasks'
import { useSystemWindowHook } from '@/hooks/systemWindowHooks'
import { useRoute } from 'vue-router'
import { useSystemSettingStore } from '@/stores/desk/systemSetting'
import type { PropType } from 'vue'

export default defineComponent({
  name: 'systemWindow',
  props: {
    appId: {
      type: String as PropType<string>,
      required: true
    },
    taskId: {
      type: String as PropType<string>,
      required: true
    },
    title: {
      type: String as PropType<string>,
      default: ''
    },
    position: {
      type: Array as PropType<number[]>,
      default: () => [0, 0]
    },
    size: {
      type: Array as PropType<number[]>,
      default: () => [innerWidth / 4, innerHeight / 4]
    },
    minSize: {
      type: Array as PropType<number[]>,
      default: () => [0, 0]
    },
    maxSize: {
      type: Array as PropType<number[]>,
      default: () => [0, 0]
    },
    isDrag: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    isFull: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    isMax: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    isMin: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    isResize: {
      type: Boolean as PropType<boolean>,
      default: true
    },
    isTray: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    isTaskBar: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    isTopBar: {
      type: Boolean as PropType<boolean>,
      default: true
    },
    componentData: {
      type: Object as PropType<{
        [key: string]: unknown
      }>,
      default: () => ({})
    }
  },
  emits: ['dragEnd', 'resizeEnd', 'close', 'minMax', 'focus', 'min', 'hidden'],
  setup(props, ctx) {
    const route = useRoute()
    const runningTasksStore = useRunningTasksStore()
    const systemSettingStore = useSystemSettingStore()
    const { dragStart, dragResizeStart, systemWindowDom, handleMousedownDrag, handleResizeMouseDown } =
      useSystemWindowHook(props.appId, props.taskId)
    const systemWindowStyle = computed(() => {
      const isMainWin = route.path === '/default/desk'
      const screenLeft = isMainWin ? 0 : systemSettingStore.$state.mainDesk[0]
      return {
        minWidth: `${props.minSize[0] || ''}px`,
        minHeight: `${props.minSize[1] || ''}px`,
        maxWidth: `${props.maxSize[0] || ''}px`,
        maxHeight: `${props.maxSize[1] || ''}px`,
        left: `${props.position[0] - screenLeft}px`,
        top: `${props.position[1]}px`,
        width: `${props.size[0]}px`,
        height: `${props.size[1]}px`
      }
    })

    // 窗口关闭
    const handleClose = () => {
      ctx.emit('focus')
      ctx.emit('close')
    }

    const handleMaxMin = () => {
      ctx.emit('minMax')
      ctx.emit('focus')
    }

    const handleSystemMousedown = () => {
      ctx.emit('focus')
    }

    // 最小化
    const handleMinimization = () => {
      if (!systemWindowDom.value) return
      // 当处于没有任务栏条时，直接隐藏
      if (!props.isTaskBar) {
        handleHiddenToTray()
        return
      }
      ctx.emit('focus')
      if (systemSettingStore.$state.deskAppRangeType === 'win') {
        const taskBarDom = document.querySelector(`li[data-task-bar-id="${props.taskId}"]`) as HTMLElement
        const { left, top } = taskBarDom.getBoundingClientRect()
        const scale = String(taskBarDom.offsetWidth / systemWindowDom.value?.offsetWidth)
        systemWindowDom.value?.style.setProperty('--system-window-min-scale', scale)
        runningTasksStore.setTaskPosition(props.appId, props.taskId, left, top)
      } else {
        console.log(props.taskId)
        const taskBarDom = document.querySelector(`li[data-task-bar-id="${props.taskId}"]`) as HTMLElement
        console.log(taskBarDom)
        const { left, top } = taskBarDom.getBoundingClientRect()
        const scale = String(taskBarDom.offsetWidth / systemWindowDom.value?.offsetWidth)
        systemWindowDom.value?.style.setProperty('--system-window-min-scale', scale)
        runningTasksStore.setTaskPosition(props.appId, props.taskId, left, top)
      }

      ctx.emit('min')
    }

    // 隐藏到托盘
    const handleHiddenToTray = () => {
      if (!systemWindowDom.value) return
      ctx.emit('focus')
      if (systemSettingStore.$state.deskAppRangeType === 'win') {
        const trayIconDom = document.querySelector(`dd[data-tray-id="${props.taskId}"]`) as HTMLElement
        const { left, top } = trayIconDom.getBoundingClientRect()
        const scale = String(trayIconDom.offsetWidth / systemWindowDom.value?.offsetWidth)
        systemWindowDom.value?.style.setProperty('--system-window-tray-scale', scale)
        runningTasksStore.setTaskPosition(props.appId, props.taskId, left, top)
      }
      ctx.emit('hidden')
    }

    provide(
      'position',
      computed(() => props.position)
    )
    provide(
      'isMax',
      computed(() => props.isMax)
    )
    provide('appId', props.appId)
    provide('taskId', props.taskId)
    provide('componentData', props.componentData)
    provide('childClose', handleClose)
    provide('childMinimization', handleMinimization)
    provide('childMaxMin', handleMaxMin)
    provide('childHiddenToTray', handleHiddenToTray)

    return {
      dragStart,
      dragResizeStart,
      systemWindowDom,
      systemWindowStyle,
      systemSettingStore,
      runningTasksStore,
      handleClose,
      handleMaxMin,
      handleMousedownDrag,
      handleResizeMouseDown,
      handleHiddenToTray,
      handleMinimization,
      handleSystemMousedown
    }
  }
})
</script>

<style scoped lang="scss">
@import '@/assets/scss/mixin';
@import '@/assets/scss/common';

.system-window {
  position: fixed;
  transition: all 0.3s $cubic;

  &.full {
    z-index: calc(#{$z-index-window-lock} - 1) !important;
    transition: all 0.3s ease-out;
    width: 100vw !important;
    height: 100vh !important;
    left: 0 !important;
    top: 0 !important;

    &.no-drag-bar {
      height: 100vh;
    }

    > .inner {
      box-shadow: none;
      border: none;
    }
  }

  &.max {
    transition: all 0.3s ease-out;
    width: 100vw !important;
    height: calc(100vh - $task-bar-height) !important;
    left: 0 !important;
    top: 0 !important;

    &.no-drag-bar {
      height: calc(100vh - $task-bar-height) !important;
    }

    > .inner {
      box-shadow: none;
      border: none;
    }
  }

  &.drag {
    transition: none !important;
  }

  &.min {
    opacity: 0;
    transition:
      all 0.3s,
      opacity 0.3s !important;
    transform-origin: left top;
    transform: scale(var(--system-window-min-scale, 0));
  }

  &.tray {
    transition:
      all 0.3s,
      opacity 0.1s !important;
    transform-origin: left top;
    transform: scale(var(--system-window-tray-scale, 0)) skewX(60deg) rotateZ(45deg);
  }

  &.ios {
    border-radius: 10px;
    overflow: hidden;

    &.max {
      border-radius: 6px;
      top: $task-bar-height !important;
      height: calc(100vh - $task-bar-height - 90px) !important;
    }
  }

  &.win-create-enter-active,
  &.win-create-leave-active {
    transform: scale(1);
    transition: all 0.3s $cubic;
  }

  &.win-create-enter-from,
  &.win-create-leave-to {
    opacity: 0;
    transform: scale(0.5);
  }

  .inner {
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    border: 1px solid #333;
    box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.5);

    .system-drag-bar {
      display: flex;
      justify-content: space-between;
      align-items: center;
      height: $system-drag-bar-height;
      color: var(--system-modal-drag-color);
      background-color: var(--system-modal-drag-bg-color);

      .system-button {
        display: flex;
        height: 100%;

        > span {
          display: inline-flex;
          justify-content: center;
          align-items: center;
          width: 48px;
          height: 100%;

          &:hover {
            @include hover-model;
            background-color: var(--system-modal-drag-bg-hover-color);

            &:last-of-type {
              color: #fff;
              background-color: rgb(232, 17, 35);
            }
          }
        }
      }

      .system-button-ios {
        display: flex;
        align-items: center;
        height: 100%;
        gap: 8px;
        padding-left: 20px;
        padding-right: 20px;

        &.blur {
          background-color: var(--ios-blur);
        }

        > span {
          width: 12px;
          height: 12px;
          border-radius: 50%;
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 10px;
          color: #000;

          &:hover {
            i {
              display: inline-block;
            }
          }

          > i {
            display: none;
          }

          &:nth-of-type(1) {
            background-color: var(--ios-close);
          }

          &:nth-of-type(2) {
            background-color: var(--ios-min);
          }

          &:nth-of-type(3) {
            background-color: var(--ios-max);
          }
        }
      }
    }

    .sort {
      width: 100%;
      height: calc(100% - $system-drag-bar-height);
    }
  }

  .no-top-bar {
    width: 100%;
    height: 100%;
  }

  .change-resize {
    .modal {
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      top: 0;
      z-index: 10;
    }

    span {
      position: absolute;
      z-index: 5;
      display: inline-block;
      background-color: transparent;

      &.row {
        top: 5px;
        bottom: 5px;
        width: 2px;
        cursor: ew-resize;

        &.left {
          left: 0;
        }

        &.right {
          right: 0;
        }
      }

      &.col {
        left: 5px;
        right: 5px;
        height: 2px;
        cursor: ns-resize;

        &.top {
          top: 0;
        }

        &.bottom {
          bottom: 0;
        }
      }

      &.box {
        z-index: 10;
        width: 5px;
        height: 5px;

        &.top-left {
          top: 0;
          left: 0;
          cursor: nwse-resize;
        }

        &.top-right {
          top: 0;
          right: 0;
          cursor: nesw-resize;
        }

        &.bottom-right {
          bottom: 0;
          right: 0;
          cursor: nwse-resize;
        }

        &.bottom-left {
          bottom: 0;
          left: 0;
          cursor: nesw-resize;
        }
      }
    }
  }
}
</style>
